#pragma once

#include <map>

typedef struct
{
    const GUID guidIntf;
    const GUID guidClass;
} stClassEntryIndex;

typedef struct
{
    const stIntfEntry* const  pIntfEntry;
    const stClassEntry* const pClassEntry;
} stClassEntryData;

__inline bool operator < (const stClassEntryIndex& _Left, const stClassEntryIndex& _Right)
{
    int n = memcmp(&_Left.guidIntf, &_Right.guidIntf, sizeof(IID));
    if(n != 0)
        return (n < 0);
    else
        return (memcmp(&_Left.guidClass, &_Right.guidClass, sizeof(CLSID)) < 0);
}

class CClassEntryMgr
{
public:
    CClassEntryMgr();
    virtual ~CClassEntryMgr();

    void UnInitClassEntryMgr();

public:
    HRESULT defRegisterClassEntry(const stIntfEntry* pIntfEntry, const stClassEntry* pClassEntry);
    HRESULT CreateObject(REFGUID intfIID, REFCLSID refCLSID, IXBaseObj** pObj);

protected:
    // This method will increase ref count of pObj.
    HRESULT CreateObjectHelper(REFCLSID refCLSID, REFGUID intfIID, IXBaseObj** pObj);
    HRESULT GetSkinObjectHelper(REFGUID intfIID, REFCLSID clsid, IXBaseObj** pObj);

protected:
    typedef std::map<stClassEntryIndex, stClassEntryData> ClassEntryMap;
    ClassEntryMap           m_ClassEntryMap;

    typedef std::map<stClassEntryIndex, IXBaseObj*> SingletonObjectStoreMap;
    SingletonObjectStoreMap m_SingletonObjectStoreMap;
};
